import com.liangsong.designpattern.chain.ClassAdviser;
import com.liangsong.designpattern.chain.GradeLeader;
import com.liangsong.designpattern.chain.LeaveRequest;
import com.liangsong.designpattern.chain.Master;
import com.liangsong.designpattern.command.*;
import com.liangsong.designpattern.composite.Department;
import com.liangsong.designpattern.composite.Emp;
import com.liangsong.designpattern.composite.Team;
import com.liangsong.designpattern.strategy.*;
import com.liangsong.designpattern.factory.*;
import com.liangsong.designpattern.factory.common.Baozi;
import com.liangsong.designpattern.factory.common.Cake;
import com.liangsong.designpattern.singleton.HungrySingleton;
import com.liangsong.designpattern.singleton.LazySingleton;
import com.liangsong.designpattern.singleton.StaticSingleton;
import com.liangsong.designpattern.template.AbstractOrderFood;
import com.liangsong.designpattern.template.KFC;
import com.liangsong.designpattern.template.StarBucks;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Application {
    public static void main(String[] args) {
        HungrySingleton hungrySingleton = HungrySingleton.getInstance();
        HungrySingleton hungrySingleton1 = HungrySingleton.getInstance();
        System.out.println(hungrySingleton1==hungrySingleton);
        hungrySingleton.test();//


        LazySingleton lazySingleton = LazySingleton.getInstance();
        LazySingleton lazySingleton1 = LazySingleton.getInstance();
        System.out.println(lazySingleton1==lazySingleton);
        lazySingleton.test();

        StaticSingleton staticSingleton = StaticSingleton.getInstance();
        StaticSingleton staticSingleton1 = StaticSingleton.getInstance();
        System.out.println(staticSingleton1==staticSingleton);
        staticSingleton.test();



        new TraditionalFactory().createBaozi("pork");//这种直接就完成了。
        new TraditionalFactory().createBaozi("suancai");



        Baozi baozi3 = SimpleFactory.createBaozi("pork");//这种还需要再制作？
        baozi3.prepare();
        baozi3.make();
        baozi3.braise();
        /*
        * 优点：
        简单工厂模式实现简单，易于理解和使用；
        可以对对象的创建进行集中管理，客户端和具体实现解耦。
        缺点：
        工厂类负责创建所有对象，如果需要添加新类型的产品，则需要修改工厂类的代码，这违反了开闭原则；
        工厂类职责过重，导致单一职责原则被破坏。
        适用场景：
        工厂类负责创建的对象较少，客户端不需要知道对象的创建过程；
        客户端需要根据传递的参数来获取对应的对象。
        *
        *
        * */


        IMeFactory factory = new BeefFactory();
        Baozi baozi4 = factory.createBaozi();
        baozi4.prepare();
        baozi4.make();
        baozi4.braise();
        /*
        优点：
        方法工厂模式具有良好的可扩展性，如果需要添加新类型的产品，只需要添加对应的工厂方法即可；
        与简单工厂模式相比，方法工厂模式更符合开闭原则和单一职责原则。
        缺点：
        需要客户端自行选择使用哪个工厂方法，不能像简单工厂模式那样直接传参获取对应对象，因此对客户端的编写有一定要求。
        适用场景：
        应用中需要创建的对象较少，但是需要具备良好的可扩展性；
        客户端可以自行选择创建哪种对象。
        * */


        BJFactory factory1 = new BJFactory();
        Cake cake = factory1.createCake("suancai");
        cake.prepare();
        cake.make();
        cake.braise();
        Baozi baozi5 = factory1.createBaozi("pork");
        baozi5.prepare();
        baozi5.make();
        baozi5.braise();
        //如果新增一种类型，需要新增类、重写。

        /*
        优点：
        抽象工厂模式可以创建多个产品族的产品，这些产品之间有相互依赖或约束关系，有助于保持系统的一致性和稳定性；
        客户端与具体产品解耦，通过产品族的方式进行管理。
        缺点：
        抽象工厂模式增加了系统的抽象性和理解难度，不易于理解和修改；
        新增产品族时需要修改工厂接口、工厂实现类和产品类，增加了系统的复杂性。
        适用场景：
        系统需要一系列相互依赖或约束的产品；
        客户端不需要知道具体产品的创建过程，只需要知道产品族即可。
        * */

        VideoStrategy v1 = new DyVideo();
        VideoStrategy v2 = new KsVideo();
        VideoStrategy v3 = new VxVideo();
        ArrayList<VideoStrategy> videoStrategyList = new ArrayList<>();
        videoStrategyList.add(v1);
        videoStrategyList.add(v2);
        videoStrategyList.add(v3);
        VideoContext context = new VideoContext(videoStrategyList);

        VideoStrategy v = context.getVideoStrategy("Vx");
        System.out.println(v.play());
        VideoStrategy vv = context.getVideoStrategy("Dy");
        System.out.println(vv.play());


        AbstractOrderFood order = new KFC();
        order.order();
        AbstractOrderFood order2 =new StarBucks();
        order2.order();


        Chef chef = new Chef();
        CookC cookC = new CookC(chef);
        Waiter waiter = new Waiter();
        waiter.setCommand(cookC);
        waiter.order();

        EditText editText = new EditText();
        editText.setText("hello");
        Bold bold = new Bold(editText);
        bold.execute();
        System.out.println(editText.getText());
        Italic italic = new Italic(editText);
        italic.execute();
        italic.undo();
        bold.undo();

        LeaveRequest leaveRequest = new LeaveRequest();
        leaveRequest.setRequestName("liangsong");
        leaveRequest.setDays(5);
        Master master = new Master("li",null);
        GradeLeader gradeLeader = new GradeLeader("ma", master);
        ClassAdviser classAdviser = new ClassAdviser("zhang", gradeLeader);
        classAdviser.Approve(leaveRequest);


        /*
        * 组合模式
        * */
        Emp e1 = new Emp("liangsong");
        Emp e2 = new Emp("zhangyiwen");
        ArrayList<Emp> listteam = new ArrayList<>();
        listteam.add(e1);
        listteam.add(e2);
        Team team = new Team(listteam);
        ArrayList<Team> listdepartment = new ArrayList<>();
        listdepartment.add(team);
        Department department = new Department(listdepartment);
        department.showAllName();


    }
}
